#include <iostream>
#include <thread>
#include <vector>
#include <string>
#include <mutex>
#include <chrono>
#include <condition_variable>
using namespace std;

//void Print(size_t n, const string& s)
//{
//    cout << this_thread::get_id() << endl;
//    for (size_t i = 0;i <= n;i++)
//    {
//        cout << s << ":" << i << endl;
//    }
//}
//int main()
//{
//	/*char  ch = 'A' + 32;
//	printf("%d", ch);*/


//    //1.带参构造线程对象，创建可执行线程
//    //2.先创建空线程对象，移动构造/移动赋值，把右值线程对象转移给空线程对象
//    //thread t1(Print, 3, "thread" + std::to_string(1));
//    //cout << "thread1 id is:" << t1.get_id() << endl;
//    //t1.detach();
//    //t1.join();//线程等待
//    
//    int x1 = 0;
//    int x2 = 9;
//    //thread t1([x1](){x1++;});
//    thread t2([&x2](){x2++;});
//    t1.join();
//    t2.join();
//    cout << x1 << " " << x2 << endl;
//	return 0;
//}


mutex m;
int a = 9;
void ThreadFunc1(int& x,const int n)
{
    for (int i = 0;i < n;++i)
    {
        m.lock();
        ++x;
        cout << "thread1：" << x << endl;
        m.unlock();
    }
}
void ThreadFunc2(int* x,const int n)
{
    for (int i = 0;i < n;++i)
    {
        m.lock();
        (*x)++;
        cout << "thread2：" << *x << endl;
        m.unlock();
    }
}

//递归
//void func(int i)
//{
//    if (i > 0)
//    {
//        cout << i << endl;
//        func(i - 1);
//    }
//    cout << i << endl;
//}

//实现lock_guard
template <typename Lock>
class LockGuard
{
public:
    LockGuard(Lock& _mutex)
        :mutex(_mutex)
    {
        mutex.lock();
    }
    ~LockGuard()
    {
        mutex.unlock();
    }
private:
    Lock& mutex;
};

//两线程交替打印奇数和偶数
void printbyThread()
{
    mutex mx;//互斥锁
    condition_variable cv;//条件变量
    /*int n = 0;
    cin >> n;*/
    int x = 0;
    bool flag = false;
    thread t1([&]() {
        for (int i = 0;i < 5;++i)
        {
            unique_lock<mutex> lock(mx);
            if (flag)
                cv.wait(lock); //该线程进入到条件变量中阻塞等待，并且释放了锁
            cout << "t1 id is " << this_thread::get_id() << "：" << x << endl;
            ++x;
            flag = true;
            cv.notify_one(); //唤醒在条件变量中阻塞等待的线程
        }
        });
    t1.detach();
    thread t2([&]() {
        for (int i = 0;i < 5;++i)
        {
            unique_lock<mutex> lock(mx);
            if (!flag)
                cv.wait(lock); //condition_variable中的wait的参数必须是unique_lock,因为unique_lock可以不只在unique_lock对象析构时解锁
            cout << "t2 id is " << this_thread::get_id() << "：" << x << endl;
            ++x;
            flag = false;
            cv.notify_one(); //if no threads are waiting,the function does nothing
        }
        });
    t2.detach();
    this_thread::sleep_for(chrono::seconds(3));
   /* t1.join();
    t2.join();*/

    //分析：
    //情况1：线程t1竞争到锁资源，t2此时就阻塞了，然后t1执行cv.notify_one();此时条件变量中没有阻塞等待的线程，什么事也不做。
    //情况2：线程t2先竞争到锁资源，cv.wait(lock),t2进入条件变量中阻塞等待，然后释放锁，然后t1获取锁资源，向下执行，cv.notify_one(),唤醒t2
}

int main()
{
    /*mutex mx;
    int n = 0;
    int a = 1000;*/
   /* thread(ThreadFunc1, std::ref(n), a).detach();
    thread t2(ThreadFunc2, &n,a);
    t2.detach();
    this_thread::sleep_for(chrono::seconds(5));*/
    /*thread t1([&mx, &n,a]() {
        for (int i = a;i > 0;i--)
        {
            mx.lock();
            ++n;
            cout <<"thread1："<< n << endl;
            mx.unlock();
        }});
    thread t2([&mx, &n,a]() {
        for (int i = a;i > 0;i--)
        {
            mx.lock();
            ++n;
            cout << "thread2：" << n << endl;
            mx.unlock();
        }});*/
    /*t1.join();
    t2.join();*/

    //auto lam = [](int a)->int {int x = 0;x = a;return x;};//lambda表达式函数体也是创建栈帧，函数退出栈帧销毁，该析构的析构

    /*if (0)
        cout << 1 << endl;
    else if (3)
        cout << 2 << endl;
    else if (4)
        cout << 4 << endl;*/


    printbyThread();
    return 0;
}